/*
 * Copyright (c) 2023 iQi.Co.Ltd. All rights reserved.
 */
 
using IQIGame.Onigao.Framework;
using System.Collections.Generic;
using System.Linq;
using System;
using NetProtocol.Enum;

namespace NetProtocol.POD {

	/// <summary>
	///  创建关卡数据
	/// module : structs_internal
	/// </summary>
	public class CreateLevelPOD : IPOD 
    {
        public readonly static Func<CreateLevelPOD> FACTORY = () => new CreateLevelPOD();
		public static Func<CreateLevelPOD> DynamicFactory = FACTORY;
        
		/*-- members --*/
		/// <summary>
        ///  local作临时属性更好，允许动态切换
        /// </summary>
		public bool isLocal;
		/// <summary>
        /// 
        /// </summary>
		public long id;
		/// <summary>
        /// 
        /// </summary>
		public int randomSeed;
		/// <summary>
        /// 
        /// </summary>
		public int cid;
		/// <summary>
        /// 
        /// </summary>
		public long hostPlayerId;
		/// <summary>
        /// 
        /// </summary>
        private List<long> m_allPlayers;
		/// <summary>
        /// 注意, 每个服务器运行时类型不一样, 游戏服序列化前是byte[](可能为null), 以bytes传输, 逻辑层在网络层反序列化为LevelSavePOD使用
        /// </summary>
        public object saveData;
        public static Action<object, SOutputStream> Serial_saveData;
        public static Func<SInputStream, object> UnSerial_saveData;
		
		
        public List<long> allPlayers
        {
            get
            {
                if(m_allPlayers == null)
                {
                    m_allPlayers = new();
                }
                return m_allPlayers;
            }
            private set => m_allPlayers = value;
        }
        public List<long> unsafe_allPlayers
        {
        	get => m_allPlayers;
        	set => m_allPlayers = value;
        }
		
		/*-- constructors --*/
		public CreateLevelPOD() {}
		public CreateLevelPOD(bool isLocal, long id, int randomSeed, int cid, long hostPlayerId, List<long> allPlayers, object saveData) {
			this.isLocal = isLocal;
			this.id = id;
			this.randomSeed = randomSeed;
			this.cid = cid;
			this.hostPlayerId = hostPlayerId;
			this.m_allPlayers = allPlayers;
			this.saveData = saveData;
		}
	      public void Serial(SOutputStream _out) {
            _out.Write_boolean(isLocal);
            _out.Write_long(id);
            _out.Write_int(randomSeed);
            _out.Write_int(cid);
            _out.Write_long(hostPlayerId);
            _out.Write_list_long(m_allPlayers); 
            Serial_saveData.Invoke(saveData, _out);
        }
        
        public void UnSerial(SInputStream _in) {
            if(!_in.HasRemaining()) return;
            isLocal = _in.Read_boolean();
            if(!_in.HasRemaining()) return;
            id = _in.Read_long();
            if(!_in.HasRemaining()) return;
            randomSeed = _in.Read_int();
            if(!_in.HasRemaining()) return;
            cid = _in.Read_int();
            if(!_in.HasRemaining()) return;
            hostPlayerId = _in.Read_long();
            if(!_in.HasRemaining()) return;
            m_allPlayers = _in.Read_list_long();
            if(!_in.HasRemaining()) return;
            saveData = UnSerial_saveData.Invoke(_in);
        }
		
		public CreateLevelPOD Clone() {
            CreateLevelPOD o = DynamicFactory();
            o.isLocal = isLocal;
            o.id = id;
            o.randomSeed = randomSeed;
            o.cid = cid;
            o.hostPlayerId = hostPlayerId;
            if (m_allPlayers != null) {
                o.m_allPlayers = new (m_allPlayers);
            }
            o.saveData = saveData;
            return o;
        }
        
        public void Clear() {
            isLocal = default;
            id = default;
            randomSeed = default;
            cid = default;
            hostPlayerId = default;
            m_allPlayers = default;
            saveData = default;
        }
		
        public override string ToString() {
			string str = "";
			str += "CreateLevelPOD [";
			str += "isLocal=";
			str += isLocal;
			str += ", id=";
			str += id;
			str += ", randomSeed=";
			str += randomSeed;
			str += ", cid=";
			str += cid;
			str += ", hostPlayerId=";
			str += hostPlayerId;
			str += ", allPlayers=";
			str += m_allPlayers.ToString<long>();
			str += ", saveData=";
			str += saveData;
			str += "]";
			return str;
		}
		
	}
}